<template>
  <el-card>
    <el-form :inline="true" :model="searchParam" ref="searchForm">
      <el-form-item label="菜单名称">
        <el-input
          placeholder="请输入菜单名称"
          clearable
          v-model="searchParam.menuName"
          @keyup.enter="queryTreeData"
        ></el-input>
      </el-form-item>
      <el-form-item label="菜单状态">
        <el-select
          v-model="searchParam.status"
          placeholder="请选择状态"
          @keyup.enter="queryTreeData"
        >
          <el-option
            v-for="(value, key, index) in selectData.statusObj"
            :key="index"
            :label="value"
            :value="key"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="菜单类型">
        <el-select
          v-model="searchParam.menuType"
          placeholder="请选择类型"
          @keyup.enter="queryTreeData"
        >
          <el-option
            v-for="(value, key, index) in selectData.typeObj"
            :key="index"
            :label="value"
            :value="key"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <commonBtn
          :value="'搜索'"
          :type="'primary'"
          :icon="'search'"
          :plain="true"
          @click="queryTreeData"
        ></commonBtn>
        <commonBtn
          :value="'重置'"
          :icon="'refresh'"
          @click="refreshFormFn"
        ></commonBtn>
      </el-form-item>
    </el-form>
    <el-row>
      <commonBtn
        :value="'新增'"
        :type="'primary'"
        :icon="'plus'"
        :plain="true"
        @click="addMenuFn"
      ></commonBtn>
      <commonBtn
        :value="'展开/折叠'"
        :type="'info'"
        :icon="'sort'"
        :plain="true"
        @click="changeExpand"
      ></commonBtn>
    </el-row>

    <el-table
      :data="searchParam.data"
      row-key="id"
      default-expand-all
      ref="xTree"
      lazy
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      v-loading="isLoad"
      style="width: 100%"
    >
      <el-table-column
        label="菜单名称"
        prop="menuName"
        show-overflow-tooltip
        width="300"
      ></el-table-column>
      <el-table-column label="排序" prop="orderNum"></el-table-column>
      <el-table-column label="图标" prop="menuName">
        <template #default="scope">
          <i :class="scope.row.icon" />
        </template>
      </el-table-column>
      <el-table-column
        label="权限标识"
        prop="permCode"
        show-overflow-tooltip
      ></el-table-column>
      <el-table-column
        label="路由"
        prop="path"
        align="center"
        show-overflow-tooltip
      ></el-table-column>
      <el-table-column
        label="前端组件"
        prop="component"
        show-overflow-tooltip
        align="center"
      ></el-table-column>
      <el-table-column label="菜单类型" align="center">
        <template #default="scope">
          <!-- 菜单 -->
          <el-tag
            v-if="scope.row.menuType === '0'"
            type="warning"
            v-text="scope.row.menuTypeDict"
          ></el-tag>
          <!-- 方法 -->
          <el-tag
            v-if="scope.row.menuType === '1'"
            type="danger"
            v-text="scope.row.menuTypeDict"
          ></el-tag>
          <!-- 按钮 -->
          <el-tag
            v-if="scope.row.menuType === '2'"
            type="success"
            v-text="scope.row.menuTypeDict"
          ></el-tag>
        </template>
      </el-table-column>
      <el-table-column
        label="请求方式"
        align="center"
        prop="methodDict"
      ></el-table-column>
      <el-table-column label="状态" align="center">
        <template #default="scope">
          <el-tag v-if="scope.row.status == '0'">{{
            scope.row.statusDict
          }}</el-tag>
          <el-tag type="danger" v-if="scope.row.status == '1'">{{
            scope.row.statusDict
          }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column
        label="操作时间"
        prop="createTime"
        align="center"
        show-overflow-tooltip
      ></el-table-column>
      <el-table-column label="操作" fixed="right" align="center" width="160">
        <template #default="scope">
          <editBtn :value="'编辑'" @click="editMenu(scope.row)" />
          <operBtn
            :value="'新增'"
            :icon="'plus'"
            class="operBtn"
            @click="lineAdd(scope.row.id)"
          />
          <delBtn :value="'删除'" @click="delMenu(scope.row.id)" />
        </template>
      </el-table-column>
    </el-table>
    <addEdit
      :layer="layer"
      :selectData="childrenData"
      :typeObj="selectData.typeObj"
      :statusObj="selectData.statusObj"
      @getTableData="queryTreeData"
      v-if="layer.show"
    ></addEdit>
  </el-card>
</template>
<script>
import { ref, reactive, computed } from "vue";
import { queryDict } from "@/api/dictValue.js";
import { treeData, deleteMenu } from "@/api/menu.js";
import commonBtn from "_c/commonBtn/index.vue";
import editBtn from "_c/editBtn/index.vue";
import delBtn from "_c/delBtn/index.vue";
import operBtn from "_c/operBtn/index.vue";
import { ElMessage, ElMessageBox } from "element-plus";
import addEdit from "./addEdit.vue";
export default {
  components: {
    commonBtn,
    editBtn,
    delBtn,
    operBtn,
    addEdit,
  },
  setup() {
    const isLoad = ref(false);
    // 弹窗控制器
    const layer = reactive({
      show: false,
      title: "新增",
      showButton: true,
      width: 500,
    });
    //树形表格引用
    const xTree = ref(null);
    //控制树形展开与折叠
    const isExpand = ref(true);

    const searchForm = ref(null);
    //搜索条件
    const searchParam = reactive({
      menuName: "",
      status: "",
      menuType: "",
      data: [],
    });
    //用于接收数据字典数据
    const selectData = reactive({
      statusObj: {},
      typeObj: {},
      methodObj: {},
    });
    //查询字典数据
    const queryDictData = async () => {
      const { data } = await queryDict("menu_status");
      selectData.statusObj = data;
      const resp = await queryDict("menu_type");
      selectData.typeObj = resp.data;
      const method = await queryDict("menu_method");
      selectData.methodObj = method.data;
    };
    queryDictData();

    //查询树形结构
    const queryTreeData = async () => {
      isLoad.value = true;
      let params = {
        menuName: searchParam.menuName || undefined,
        status: searchParam.status || undefined,
        menuType: searchParam.menuType || undefined,
      };
      const { data } = await treeData(params);
      searchParam.data = data;
      isLoad.value = false;
    };
    queryTreeData();
    //搜索条件重置
    const refreshFormFn = () => {
      searchParam.menuName = "";
      searchParam.status = "";
      searchParam.menuType = "";
      queryTreeData();
    };
    //删除菜单
    const delMenu = async (id) => {
      if (id) {
        ElMessageBox.confirm("您确定要删除该数据以及子数据吗？", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(async () => {
          const { success } = await deleteMenu({ id: id });
          if (success) {
            ElMessage.success("删除成功");
            queryTreeData();
          }
        });
      }
    };

    //树形结构赋值 (循环数据赋值)
    const TabData = (data, status) => {
      data.forEach((i) => {
        xTree.value.toggleRowExpansion(i, status);
        if (i.children.length > 0) {
        }
      });
    };
    //展开关闭控制方法
    const changeExpand = () => {
      //设置开关标记
      isExpand.value = !isExpand.value;
      TabData(searchParam.data, isExpand.value);
    };
    //控制弹框-新增
    const addMenuFn = () => {
      layer.title = "新增菜单";
      layer.show = true;
      delete layer.row;
    };
    //递归构造数据
    const getSelectData = (obj) => {
      if (!obj) {
        return;
      }
      let temp = {};
      temp.label = obj.menuName;
      temp.value = obj.id;
      if (obj.children) {
        let arr = [];
        obj.children.forEach((item) => {
          arr.push(getSelectData(item));
        });
        temp.children = arr;
      }
      return temp;
    };
    //递归重组，子组件树形数据
    const childrenData = computed(() => {
      let obj = [];
      if (searchParam.data) {
        searchParam.data.forEach((item) => {
          obj.push(getSelectData(item));
        });
      }
      return obj;
    });
    //编辑菜单
    const editMenu = (row) => {
      row["flag"] = true;
      layer.title = "编辑菜单";
      layer.show = true;
      layer.row = row;
    };
    //行内操作： 增加
    const lineAdd = (id) => {
      layer.title = "新增下级菜单";
      layer.show = true;
      layer.row = {
        parentId: id,
      };
    };
    return {
      isLoad,
      childrenData,
      layer,
      xTree,
      searchForm,
      searchParam,
      selectData,
      refreshFormFn,
      queryDictData,
      queryTreeData,
      delMenu,
      changeExpand,
      addMenuFn,
      editMenu,
      lineAdd,
    };
  },
};
</script>
<style lang="scss" scoped>
.el-form {
  display: flex;
  justify-content: left;
}

.el-table {
  margin-top: 15px;
}
</style>
